package com.atgm.mall.gmmallcart.Service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.atgm.common.constant.CartConstant;
import com.atgm.common.exception.BizCodeEnume;
import com.atgm.common.exception.CartException;
import com.atgm.common.utils.GmMallUtils;
import com.atgm.common.utils.R;
import com.atgm.mall.gmmallcart.Service.GameShoppingService;
import com.atgm.mall.gmmallcart.dao.GameShoppingDao;
import com.atgm.mall.gmmallcart.entity.GameShoppingEntity;
import com.atgm.mall.gmmallcart.feign.MemberFeignService;
import com.atgm.mall.gmmallcart.interceptor.CartInterceptor;
import com.atgm.mall.gmmallcart.vo.UserInfoTo;
import com.atgm.mall.gmmallcart.vo.req.CartRemoveReqVo;
import com.atgm.mall.gmmallcart.vo.req.GameCartReqVo;
import com.atgm.mall.gmmallcart.vo.req.MemberWishReqVo;
import com.atgm.mall.gmmallcart.vo.resp.GameCartRespVo;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.quartz.spi.ThreadExecutor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

@Slf4j
@Service
public class GameShoppingServiceImpl extends ServiceImpl<GameShoppingDao, GameShoppingEntity> implements GameShoppingService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    @Autowired
    private MemberFeignService memberFeignService;

    @Override
    @Transactional
    public void saveCart(GameCartReqVo gameCartReqVo) {
        //判断购物车中是否存在该游戏商品
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        String gameId = gameCartReqVo.getGameId().toString();
        String gameCart = (String) cartOps.get(gameId);

        if (GmMallUtils.isEmpty(gameCart)) {  //如果不存在该游戏商品
            GameShoppingEntity gameShoppingEntity = new GameShoppingEntity();
            BeanUtils.copyProperties(gameCartReqVo, gameShoppingEntity);
            //生成购物车id
            long id = IdWorker.getId();
            gameShoppingEntity.setId(id);
            gameShoppingEntity.setDeleted(0);  //未删除
            gameShoppingEntity.setCreateTime(new Date());
            int count = baseMapper.insert(gameShoppingEntity);
            if (count != 1) {
                throw new CartException("添加购物车失败", BizCodeEnume.ADD_SHOPPING_CART.getCode());
            }

            R r = memberFeignService.isWished(gameCartReqVo.getGameId(), gameCartReqVo.getMemberId());
            Integer data = r.getData(new TypeReference<Integer>() {});

            gameCartReqVo.setId(id);
            gameCartReqVo.setIsWished(data);
            //保存数据到数据库、redis
            String jsonCart = JSON.toJSONString(gameCartReqVo);
            cartOps.put(gameId, jsonCart);
        }
    }

    @Override
    public Long queryCartNum() {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        return cartOps.size();
    }

    @Override
    public List<GameCartRespVo> querCartList() {
        List<GameCartRespVo> gameCartRespVos = new ArrayList<>();
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        List<Object> values = cartOps.values();
        if (GmMallUtils.isNotEmpty(values)) {
            gameCartRespVos = values.stream().map(value -> {
                String str = (String) value;
                return JSON.parseObject(str, GameCartRespVo.class);
            }).collect(Collectors.toList());
        }
        return gameCartRespVos;
    }

    @Override
    @Transactional
    public void addWishInCartPage(MemberWishReqVo memberWishReqVo) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        String json = (String) cartOps.get(memberWishReqVo.getGameId().toString());
        GameCartReqVo gameCartReqVo = JSON.parseObject(json, GameCartReqVo.class);

        //添加到心愿单
        R r = memberFeignService.addMemberWish(memberWishReqVo);
        if (0 != r.getCode()) {
            throw new CartException("添加心愿单失败", BizCodeEnume.ADD_GAME_WISH.getCode());
        }

        //修改redis中数据
        gameCartReqVo.setIsWished(1);  //添加心愿单
        String jsonString = JSON.toJSONString(gameCartReqVo);
        cartOps.put(memberWishReqVo.getGameId().toString(), jsonString);
    }

    @Override
    public void deleteCartInfo(Long gameId) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        String json = (String) cartOps.get(gameId.toString());
        if (GmMallUtils.isEmpty(json)) {
            throw new CartException("删除购物车商品失败", BizCodeEnume.DELETE_SHOPPING_CART.getCode());
        }
        GameCartReqVo gameCartReqVo = JSON.parseObject(json, GameCartReqVo.class);
        Long id = gameCartReqVo.getId();
        int count = baseMapper.deleteById(id);
        if (count != 1) {
            throw new CartException("删除购物车商品失败", BizCodeEnume.DELETE_SHOPPING_CART.getCode());
        }
        //删除redis中记录
        cartOps.delete(gameId.toString());
    }

    @GlobalTransactional
    @Override
    public void removeCartByMemberId(CartRemoveReqVo cartRemoveReqVo) {
        BoundHashOperations<String, Object, Object> ops = getCartOps();

        //批量删除购物车信息
        List<Long> ids = new ArrayList<>();
        List<Long> gameIds = cartRemoveReqVo.getGameIds();
        gameIds.forEach(gameId -> {
            String json = (String) ops.get(gameId.toString());
            GameCartReqVo gameCartReqVo = JSON.parseObject(json, GameCartReqVo.class);
            ids.add(gameCartReqVo.getId());
        });
        this.removeByIds(ids);

        //删除redis中数据
        gameIds.forEach(gameId -> {
            ops.delete(gameId.toString());
        });
    }

    /**
     * 获取要操作的redis集合
     * @return
     */
    public BoundHashOperations<String, Object, Object> getCartOps() {
        //获取登录用户
        UserInfoTo userInfoTo = CartInterceptor.toThreadLocal.get();
        Long userId = userInfoTo.getUserId();
        String key = CartConstant.CART_PREFIX + userId;
        BoundHashOperations<String, Object, Object> ops =
                stringRedisTemplate.boundHashOps(key);
        return ops;
    }
}
